﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Configuration;
using YLPublicService.TransferModel;

namespace YLPublicService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class UserService : ServiceBase<User>, IUserService
    {
        public static int[] FtpServerIPV4;
        public static int FtpServerPort;
        static UserService()
        {
            FtpServerIPV4 = ConfigurationManager.AppSettings["FtpIp"].Split('.').Select(v => int.Parse(v)).ToArray();
            FtpServerPort = int.Parse(ConfigurationManager.AppSettings["FtpPort"]);
        }
        private readonly int randomPassLen = int.Parse(ConfigurationManager.AppSettings["RandomPassLength"]);

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="loginName"></param>
        private void disableUserOnFtp(string loginName)
        {
            settingManager.RandomPassword(loginName, randomPassLen);
        }
        public override void LoginOut(Guid guid)
        {
            disableUserOnFtp(getCurrentUser(guid).LoginName);//loginout后当前登录guid 就没了，所以要提前调用
            base.LoginOut(guid);
        }

        //返回ftp 地址 密码等
        public TransferModel.FtpServerInfo RequestFtpServerInfo(Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }
            User user = getCurrentUser(guid);
            if (user.Enabled == false)
                return null;
            TransferModel.FtpServerInfo info = new TransferModel.FtpServerInfo();
            info.IPV4 = FtpServerIPV4;
            info.Port = FtpServerPort;
            var pwd = settingManager.RandomPassword(user.LoginName, randomPassLen);
            info.ClientLoginName = user.LoginName;
            info.ClientPassWord = pwd;
            return info;
        }
        /// <summary>
        /// 获取帐户余额
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public TransferModel.UserAccount GetAccount(Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }
            int uid = getCurrentUser(guid).UserID;
            dbContext.Refresh(RefreshMode.OverwriteCurrentValues, dbContext.UserAccounts);
            var userAccount = dbContext.UserAccounts.Where(ua => ua.UserID == uid).First();
            TransferModel.UserAccount tua = new TransferModel.UserAccount() { UserID = userAccount.UserID, Money = userAccount.Money };
            return tua;
        }

        private IEnumerable<TransferModel.WorkItem> getWorkItems(Func<View_UserAndItem, bool> predicate, Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }

            User user = getCurrentUser(guid);
            var items = dbContext.View_UserAndItems
                .Where(predicate)
                .Select(ui =>
                        new TransferModel.WorkItem
                        {
                            TemplateName = ui.TemplateName,
                            Time = ui.Time,
                            boyName = ui.boyName,
                            grilName = ui.grilName,
                            Status = ui.discription,
                            DBTime = ui.DBTime
                        }
                    );
            return items;
        }

        public IEnumerable<TransferModel.WorkItem> GetWorkItems(Guid guid)
        {
            return getWorkItems(wi => true, guid);
        }

        public IEnumerable<TransferModel.WorkItem> GetWorkItems(DateTime start, DateTime end, Guid guid)
        {
            return getWorkItems(wi => wi.DBTime >= start && wi.DBTime <= end, guid);
        }
        /// <summary>
        /// 添加工作项包括以下内容：
        /// 添加一个物理文件夹
        /// 在数据库添加一条状态是正在上传的工作项
        /// </summary>
        /// <param name="item"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool AddWorkItem(TransferModel.WorkItem item, Guid guid)
        {
            if (!isOnline(guid))
            {
                return false;
            }
            var user = getCurrentUser(guid);
            #region 判断是否已经添加了该项
            var x = from i in dbContext.WorkItems
                    where i.Time == item.Time
                    && i.boyName == item.grilName
                    && i.boyName == item.boyName
                    && i.TemplateName == item.TemplateName
                    select i;
            if (x.Count() > 0)
            {
                return true;
            }
            #endregion
            //添加工作项Ftp目录
            var path = settingManager.AddWorkItemDir(user.LoginName, item.boyName, item.grilName, item.TemplateName);
            var status1 = dbContext.WorkItemStatus.Where(s => s.status == TransferModel.WorkItemStatus.Uploading.GetID()).First();
            WorkItem wi = new WorkItem
            {
                TemplateName = item.TemplateName,
                Time = item.Time,
                boyName = item.boyName,
                grilName = item.grilName,
                DBTime = DateTime.Now,
                PhotoServerRelativePath = path,
                Status = status1.status
            };
            dbContext.WorkItems.InsertOnSubmit(wi);
            dbContext.SubmitChanges();
            UsersItem ui = new UsersItem
            {
                ItemID = wi.ItemID,
                UserID = user.UserID
            };
            dbContext.UsersItems.InsertOnSubmit(ui);
            dbContext.SubmitChanges();
            return true;
        }


        /// <summary>
        /// 用户名，密码正确，且帐户启用
        /// 成功则返回用户对象
        /// 注意：非数据库中的用户对象类型
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="pwd"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        protected override bool TryFindUser(string loginName, string pwd, out User user)
        {
            var ret = from u in dbContext.Users //.Where(su => su.LoginName == user.LoginName).First();
                      where u.LoginName == loginName && u.PassWord == new Binary(HashAlgorithm.getHex(pwd))
                                   && u.Enabled == true
                      select u;
            if (ret.Count() > 0)
            {
                user = ret.First();
                return true;
            }
            else
            {
                user = null;
                return false;
            }
        }


        public string[] GetTemplates(Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }
            return new string[] { "好运来", "可爱" };
        }


        public string GetFinishFileDir(string boyName, string grilName, Guid guid)
        {
            User user = getCurrentUser(guid);
            var x = from ui in dbContext.View_FinishWorkItems
                    where ui.UserID == user.UserID && ui.boyName == boyName && ui.grilName == grilName
                    select ui;
            if (x.Count() == 1)
            {
                return x.First().PhotoServerRelativePath + "/finish";
            }
            else
                return "";
        }

        public TransferModel.WorkItem[] GetFinishWorkItems(DateTime start, DateTime end, Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }
            User user = getCurrentUser(guid);
            var x = from i in dbContext.View_FinishWorkItems
                    select new TransferModel.WorkItem
                    {
                        TemplateName = i.TemplateName,
                        Time = i.Time,
                        boyName = i.boyName,
                        grilName = i.grilName,
                        Status = i.discription,
                        DBTime = i.DBTime
                    };
            return x.ToArray();
        }


        public DateTime[] GetUserWorkItemDates(Guid guid)
        {
            if (!isOnline(guid))
            {
                return null;
            }
            var user = getCurrentUser(guid);
            var ret = from i in dbContext.View_UserItemDates
                      where i.UserID == user.UserID
                      select i.DBTime;
            return ret.ToArray();
        }




        public bool UpdatedWorkItemStatus(TransferModel.WorkItem item, TransferModel.WorkItemStatus newStatus, Guid guid)
        {
            if (!isOnline(guid))
            {
                return false;
            }
            var user = getCurrentUser(guid);
            var items = dbContext.WorkItems.Where(_item =>
                _item.TemplateName == item.TemplateName
                && _item.boyName == item.boyName
                && _item.grilName == item.grilName
                && _item.Time == item.Time);
            if (items.Count() == 1)
            {
                var i = items.First();
                i.Status = newStatus.GetID();
                dbContext.SubmitChanges(ConflictMode.ContinueOnConflict);
                return true;
            }
            else
                return false;
        }
    }
}
